1. Balloon driver does not need to set M2P entry.
This is done by the populate_physmap hypercall.
2. Xen now translates foreign mappings from GMFN->MFN.
Tools are simplified because of this.
Signed-off-by: Keir Fraser <keir@xensource.com>
}
#endif /* CONFIG_X86_64 */
-void xen_machphys_update(unsigned long mfn, unsigned long pfn)
-{
- mmu_update_t u;
- if (xen_feature(XENFEAT_auto_translated_physmap)) {
- BUG_ON(pfn != mfn);
- return;
- }
- u.ptr = ((unsigned long long)mfn << PAGE_SHIFT) | MMU_MACHPHYS_UPDATE;
- u.val = pfn;
- BUG_ON(HYPERVISOR_mmu_update(&u, 1, NULL, DOMID_SELF) < 0);
-}
-
void xen_pt_switch(unsigned long ptr)
{
struct mmuext_op op;
BUG_ON(!xen_feature(XENFEAT_auto_translated_physmap) &&
phys_to_machine_mapping_valid(pfn));
- /* Update P->M and M->P tables. */
set_phys_to_machine(pfn, frame_list[i]);
- xen_machphys_update(frame_list[i], pfn);
/* Link back into the page tables if not highmem. */
if (pfn < max_low_pfn) {
void xen_pgd_unpin(unsigned long ptr);
void xen_set_ldt(unsigned long ptr, unsigned long bytes);
-void xen_machphys_update(unsigned long mfn, unsigned long pfn);
#ifdef CONFIG_SMP
#include <linux/cpumask.h>
#define virt_to_machine(virt) __pa(virt) // for tpmfront.c
#define set_phys_to_machine(pfn, mfn) do { } while (0)
-#ifdef CONFIG_VMX_GUEST
-extern void xen_machphys_update(unsigned long mfn, unsigned long pfn);
-#else /* CONFIG_VMX_GUEST */
-#define xen_machphys_update(mfn, pfn) do { } while (0)
-#endif /* CONFIG_VMX_GUEST */
typedef unsigned long maddr_t; // to compile netback, netfront
unsigned long nr_pages, unsigned int address_bits,
xen_pfn_t *extent_start)
{
-#if 0
- int i;
-#endif
xc_dominfo_t info;
int err = 0;
return -1;
}
- err = xc_domain_translate_gpfn_list(xc_handle, domid, nr_pages,
- extent_start, extent_start);
- if (err) {
- fprintf(stderr, "Failed to translate gpfn list\n");
- return -1;
- }
-
-#if 0 /* Generates lots of log file output - turn on for debugging */
- for (i = 0; i < nr_pages; i++)
- fprintf(stderr, "set_map result i %x result %lx\n", i,
- extent_start[i]);
-#endif
-
return 0;
}
#if defined(__i386__) || defined(__x86_64__)
for ( i = 0; i < tmp_nr_pages; i++)
page_array[i] = i;
- if (xc_domain_translate_gpfn_list(xc_handle, domid, tmp_nr_pages,
- page_array, page_array)) {
- fprintf(logfile, "xc_domain_translate_gpfn_list returned error %d\n",
- errno);
- exit(-1);
- }
phys_ram_base = xc_map_foreign_batch(xc_handle, domid,
PROT_READ|PROT_WRITE, page_array,
return err;
}
-int xc_domain_translate_gpfn_list(int xc_handle,
- uint32_t domid,
- unsigned long nr_gpfns,
- xen_pfn_t *gpfn_list,
- xen_pfn_t *mfn_list)
-{
- struct xen_translate_gpfn_list op = {
- .domid = domid,
- .nr_gpfns = nr_gpfns,
- };
- set_xen_guest_handle(op.gpfn_list, gpfn_list);
- set_xen_guest_handle(op.mfn_list, mfn_list);
-
- return xc_memory_op(xc_handle, XENMEM_translate_gpfn_list, &op);
-}
-
int xc_domain_max_vcpus(int xc_handle, uint32_t domid, unsigned int max)
{
DECLARE_DOMCTL;
goto error_out;
}
- if ( xc_domain_translate_gpfn_list(xc_handle, dom, nr_pages,
- page_array, page_array) )
- {
- PERROR("Could not translate addresses of HVM guest.\n");
- goto error_out;
- }
-
loadelfimage(image, xc_handle, dom, page_array, &dsi);
if ( set_hvm_info(xc_handle, dom, page_array, vcpus, acpi) )
PERROR("Could not allocate memory for PV guest.\n");
goto error_out;
}
- if ( xc_domain_translate_gpfn_list(xc_handle, dom, nr_pages,
- page_array, page_array) )
- {
- PERROR("Could not translate addresses of PV guest.\n");
- goto error_out;
- }
dsi.v_start = round_pgdown(dsi.v_start);
vinitrd_start = round_pgup(dsi.v_end);
}
shared_info_frame = domctl.u.getdomaininfo.shared_info_frame;
- if(xc_domain_setmaxmem(xc_handle, dom, PFN_TO_KB(max_pfn)) != 0) {
+ if (xc_domain_setmaxmem(xc_handle, dom, PFN_TO_KB(max_pfn)) != 0) {
errno = ENOMEM;
goto out;
}
- if(xc_domain_memory_increase_reservation(
- xc_handle, dom, max_pfn, 0, 0, NULL) != 0) {
+ for ( pfn = 0; pfn < max_pfn; pfn++ )
+ p2m[pfn] = pfn;
+
+ if (xc_domain_memory_populate_physmap(xc_handle, dom, max_pfn,
+ 0, 0, p2m) != 0) {
ERROR("Failed to increase reservation by %lx KB", PFN_TO_KB(max_pfn));
errno = ENOMEM;
goto out;
DPRINTF("Increased domain reservation by %lx KB\n", PFN_TO_KB(max_pfn));
- /* Build the pfn-to-mfn table. We choose MFN ordering returned by Xen. */
- if (xc_get_pfn_list(xc_handle, dom, p2m, max_pfn) != max_pfn) {
- ERROR("Did not read correct number of frame numbers for new dom");
- goto out;
- }
-
if(!(mmu = xc_init_mmu_updates(xc_handle, dom))) {
ERROR("Could not initialise for MMU updates");
goto out;
}
-
DPRINTF("Reloading memory pages: 0%%\n");
/*
DECLARE_HYPERCALL;
struct xen_memory_reservation *reservation = arg;
struct xen_machphys_mfn_list *xmml = arg;
- struct xen_translate_gpfn_list *trans = arg;
xen_pfn_t *extent_start;
- xen_pfn_t *gpfn_list;
- xen_pfn_t *mfn_list;
long ret = -EINVAL;
hypercall.op = __HYPERVISOR_memory_op;
goto out1;
}
break;
- case XENMEM_translate_gpfn_list:
- if ( lock_pages(trans, sizeof(*trans)) != 0 )
- {
- PERROR("Could not lock");
- goto out1;
- }
- get_xen_guest_handle(gpfn_list, trans->gpfn_list);
- if ( lock_pages(gpfn_list, trans->nr_gpfns * sizeof(xen_pfn_t)) != 0 )
- {
- PERROR("Could not lock");
- unlock_pages(trans, sizeof(*trans));
- goto out1;
- }
- get_xen_guest_handle(mfn_list, trans->mfn_list);
- if ( lock_pages(mfn_list, trans->nr_gpfns * sizeof(xen_pfn_t)) != 0 )
- {
- PERROR("Could not lock");
- unlock_pages(gpfn_list, trans->nr_gpfns * sizeof(xen_pfn_t));
- unlock_pages(trans, sizeof(*trans));
- goto out1;
- }
- break;
}
ret = do_xen_hypercall(xc_handle, &hypercall);
case XENMEM_add_to_physmap:
unlock_pages(arg, sizeof(struct xen_add_to_physmap));
break;
- case XENMEM_translate_gpfn_list:
- get_xen_guest_handle(mfn_list, trans->mfn_list);
- unlock_pages(mfn_list, trans->nr_gpfns * sizeof(xen_pfn_t));
- get_xen_guest_handle(gpfn_list, trans->gpfn_list);
- unlock_pages(gpfn_list, trans->nr_gpfns * sizeof(xen_pfn_t));
- unlock_pages(trans, sizeof(*trans));
- break;
}
out1:
unsigned int address_bits,
xen_pfn_t *extent_start);
-int xc_domain_translate_gpfn_list(int xc_handle,
- uint32_t domid,
- unsigned long nr_gpfns,
- xen_pfn_t *gpfn_list,
- xen_pfn_t *mfn_list);
-
int xc_domain_ioport_permission(int xc_handle,
uint32_t domid,
uint32_t first_port,
if ( l1e_get_flags(nl1e) & _PAGE_PRESENT )
{
+ /* Translate foreign guest addresses. */
+ nl1e = l1e_from_pfn(gmfn_to_mfn(FOREIGNDOM, l1e_get_pfn(nl1e)),
+ l1e_get_flags(nl1e));
+
if ( unlikely(l1e_get_flags(nl1e) & L1_DISALLOW_MASK) )
{
MEM_LOG("Bad L1 flags %x",
if ( likely(domid == DOMID_SELF) )
goto out;
- if ( domid == d->domain_id )
+ if ( unlikely(domid == d->domain_id) )
{
MEM_LOG("Dom %u tried to specify itself as foreign domain",
d->domain_id);
okay = 0;
}
+ else if ( unlikely(shadow_mode_translate(d)) )
+ {
+ MEM_LOG("Cannot mix foreign mappings with translated domains");
+ okay = 0;
+ }
else if ( !IS_PRIV(d) )
{
switch ( domid )
}
}
- if ( unlikely(shadow_mode_translate(d)) )
- {
- MEM_LOG("%s: can not mix foreign mappings with translated domains",
- __func__);
- info->foreign = NULL;
- okay = 0;
- }
-
out:
return okay;
}
break;
}
- if ( shadow_mode_translate(FOREIGNDOM) )
- shadow_guest_physmap_add_page(FOREIGNDOM, gpfn, mfn);
- else
- set_gpfn_from_mfn(mfn, gpfn);
+ if ( unlikely(shadow_mode_translate(FOREIGNDOM)) )
+ {
+ MEM_LOG("Mach-phys update on shadow-translate guest");
+ break;
+ }
+
+ set_gpfn_from_mfn(mfn, gpfn);
okay = 1;
- // Mark the new gfn dirty...
mark_dirty(FOREIGNDOM, mfn);
put_page(mfn_to_page(mfn));
}
ol1e = *pl1e;
- /*
- * Check that the virtual address supplied is actually mapped to
- * frame.
- */
+ /* Check that the virtual address supplied is actually mapped to frame. */
if ( unlikely(l1e_get_pfn(ol1e) != frame) )
{
MEM_LOG("PTE entry %lx for address %lx doesn't match frame %lx",
{
MEM_LOG("Cannot delete PTE entry at %p", (unsigned long *)pl1e);
rc = GNTST_general_error;
- goto out; // this is redundant & unnecessary, but informative
+ goto out;
}
out: